Include package props with env vars into target metadata
authorAnton Larin <edding.default@gmail.com>
Thu, 23 Mar 2017 14:26:40 +0000 (17:26 +0300)
committerAnton Larin <edding.default@gmail.com>
Thu, 23 Mar 2017 19:55:08 +0000 (22:55 +0300)
Previously, when changing package properties with corresponding
environment variables (such as authors, which has CARGO_PKG_AUTHORS),
it didn't invalidate the build, even though there could have been
a dependency on such variables in the source code.

This commit includes such properties (there are 3 of them in total:
authors, description and homepage) in the target metadata.

Fixes #3696.

src/cargo/ops/cargo_rustc/compilation.rs
src/cargo/ops/cargo_rustc/context.rs
tests/freshness.rs

index 37bf4008fdb69c01fe1998738d55b4f8380490e8..5192d2cadb8a0f894088516c142f6ede42432d9c 100644 (file)
@@ -146,6 +146,10 @@ impl<'cfg> Compilation<'cfg> {
         let cargo_exe = self.config.cargo_exe()?;
         cmd.env(::CARGO_ENV, cargo_exe);
 
+        // When adding new environment variables depending on
+        // crate properties which might require rebuild upon change
+        // consider adding the corresponding properties to the hash
+        // in Context::target_metadata()
         cmd.env("CARGO_MANIFEST_DIR", pkg.root())
            .env("CARGO_PKG_VERSION_MAJOR", &pkg.version().major.to_string())
            .env("CARGO_PKG_VERSION_MINOR", &pkg.version().minor.to_string())
index 756022dbc747a03d78d95c3b0d0e85eb83ef7be6..b5d01cd3efde31c8145dd87651221b7ace2ba067 100644 (file)
@@ -399,6 +399,13 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
         // to pull crates from anywhere w/o worrying about conflicts
         unit.pkg.package_id().hash(&mut hasher);
 
+        // Add package properties which map to environment variables
+        // exposed by Cargo
+        let manifest_metadata = unit.pkg.manifest().metadata();
+        manifest_metadata.authors.hash(&mut hasher);
+        manifest_metadata.description.hash(&mut hasher);
+        manifest_metadata.homepage.hash(&mut hasher);
+
         // Also mix in enabled features to our metadata. This'll ensure that
         // when changing feature sets each lib is separately cached.
         self.resolve.features_sorted(unit.pkg.package_id()).hash(&mut hasher);
index fc95cd88376c85afc7f82520c06440ca92346c16..eb7532b3490326c180a3f328a06baea32dda0187 100644 (file)
@@ -680,3 +680,44 @@ fn rebuild_if_build_artifacts_move_forward_in_time() {
 [FINISHED] [..]
 "));
 }
+
+#[test]
+fn rebuild_if_environment_changes() {
+    let p = project("env_change")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "env_change"
+            description = "old desc"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/main.rs", r#"
+            fn main() {
+                println!("{}", env!("CARGO_PKG_DESCRIPTION"));
+            }
+        "#);
+
+    assert_that(p.cargo_process("run"),
+                execs().with_status(0)
+                .with_stdout("old desc").with_stderr(&format!("\
+[COMPILING] env_change v0.0.1 ({dir})
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] `target[/]debug[/]env_change[EXE]`
+", dir = p.url())));
+
+    File::create(&p.root().join("Cargo.toml")).unwrap().write_all(br#"
+        [package]
+        name = "env_change"
+        description = "new desc"
+        version = "0.0.1"
+        authors = []
+    "#).unwrap();
+
+    assert_that(p.cargo("run"),
+                execs().with_status(0)
+                .with_stdout("new desc").with_stderr(&format!("\
+[COMPILING] env_change v0.0.1 ({dir})
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] `target[/]debug[/]env_change[EXE]`
+", dir = p.url())));
+}